package it.koutifaris.travianmap.dal.sqlservices.tile;

import it.koutifaris.travianmap.dal.RevisionService.Revision;
import it.koutifaris.travianmap.model.Village;
import it.koutifaris.travianmap.tile.Tile;
import it.koutifaris.travianmap.tile.TileBounds;
import it.koutifaris.travianmap.tile.TileLoader;
import it.koutifaris.travianmap.tile.bounds.DefaultTileBounds;
import it.koutifaris.travianmap.ui.PointToSquareHelper;

import java.util.List;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class SqlTileLoader implements TileLoader {

	private static final int TILE_SIZE = TileBounds.DEFAULT_TILE_SIZE;

	private final String TAG = SqlTileLoader.class.getName();

	private final SQLiteDatabase database;
	private final Revision revision;
	private final PointToSquareHelper pointToSquareHelper;
	private final MapDataExtractor dataExtractor;

	private String dataQuery;

	public SqlTileLoader(String serverId, SQLiteDatabase database, Revision revision) {
		this.database = database;
		this.revision = revision;

		dataExtractor = new MapDataExtractor();
		pointToSquareHelper = new PointToSquareHelper(TILE_SIZE);
	}

	@Override
	public Tile loadTileAt(int x, int y) {
		long start = System.nanoTime();

		DefaultTileBounds tileBounds = createTileBounds(x, y);
		Cursor cursor = database.rawQuery(getQuery(), getSelectionArgs(tileBounds));

		List<Village> villages = dataExtractor.getVillagesFromCursor(cursor);
		cursor.close();

		Log.d(TAG, "Time to load tile: " + (System.nanoTime() - start) / 1000000);

		return new SqlTile(villages, tileBounds);
	}

	private String getQuery() {
		if (dataQuery == null) {
			dataQuery = VillagesInBoundsQuery.getVillagesInBoundQuery();
		}

		return dataQuery;
	}

	private String[] getSelectionArgs(DefaultTileBounds tileBounds) {
		return VillagesInBoundsQuery.getSelectionArgs(revision.getId(), tileBounds);
	}

	private DefaultTileBounds createTileBounds(int x, int y) {
		int tileX = pointToSquareHelper.getSquareCornerFromPoint(x);
		int tileY = pointToSquareHelper.getSquareCornerFromPoint(y);

		return DefaultTileBounds.builder()
				.setOrigin(tileX, tileY)
				.withDefaultSize()
				.build();
	}

}
